# 大型网站架构演化发展历程

  • 初始阶段的网站架构:应用程序、数据库、文件等所有的资源都在一台服务器上
  • 应用服务和数据服务分离:应用服务器、文件服务器和数据库服务器
  • 使用缓存改善网站性能:本地缓存、远程分布式缓存
  • 使用应用服务器集群改善网站的并发处理能力:通过负载均衡调度服务器,可将来自用户浏览器的访问请求分发到应用服务器集群中的任何一台服务器上
  • 数据库读写分离:应用服务器在写数据的时候,访问主数据库,主数据库通过主从复制机制将数据更新同步到从数据库
  • 使用反向代理和 CDN 加速网站响应
  • 使用分布式文件系统和分布式数据库系统:将不同业务的数据库部署在不同的物理服务器上
  • 使用 NoSQL 和搜索引擎
  • 业务拆分:将整个网站业务分成不同的产品线
  • 分布式服务(微服务)

布式服

# 网站架构模式

  • 分层:应用层、服务层、数据层
  • 分割
  • 分布式:将不同模块部署在不同的服务器上,通过远程调用协同工作,常用方案:分布式应用和服务、分布式静态资源(动静分离)、分布式数据和存储、分布式计算
  • 集群
  • 缓存:CDN、反向代理、本地缓存、分布式缓存
  • 异步
  • 冗余:服务器冗余运行,数据冗余备份
  • 自动化
  • 安全

# 系统吞吐量

  • QPS(Queries Per Second,每秒查询率),是指一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准
  • TPS(Transactions Per Second,每秒事务数),软件测试结果的测量单位,一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程,客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数
  • RT(响应时间)
  • 系统吞吐量(Thoughput)几个重要参数:QPS(TPS)、并发数、响应时间(Latency)
    • QPS(TPS):每秒钟 request/事务数
    • 响应时间:一般取平均响应时间
    • 并发数:系统同时处理的 request/事务数
  • 计算公式
    • QPS(TPS)= 并发数/平均响应时间
    • 并发数 = QPS(TPS)* 平均响应时间

# 性能指标

  • TP,即 Top Percentile,Top 百分数
  • TP 指标:指在一个时间段内,统计该方法每次调用所消耗的时间,并将这些时间按从小到大的顺序进行排序,并取出结果为:总次数 * 指标数 = 对应 TP 指标的序号,再根据序号取出对应排序好的时间,即为 TP 指标
  • TP50、TP90 和 TP99 等指标常用于系统性能监控场景,指高于 50%、90%、99% 等百分线的情况
  • 可以认为 TP90 的意思是保证 90% 请求都能被响应的最小耗时(The tp90 is a minimum time under which 90% of requests have been served.)

TP 分位线:95line 表示 95% 的请求的响应时间比参考值要小,999line 表示 99.9% 的响应时间比参考值要小,95line 以及 99line,也称之为 tp95、tp99。

# 服务可用性

  • SLA(服务等级协议,Service Level Agreement),是在一定开销下为保障服务的性能和可用性,服务提供商与用户间定义的一种双方认可的协定。
  • 可用性 99% 表示一定时间内提供服务的停机时间
  • 计算公式:可用性指标 = 正常请求 / 全部请求

# 网站的高性能架构

# Web 前端性能优化

# 浏览器访问优化

  1. 减少 http 请求:合并 CSS、合并 JavaScript、合并图片
  2. 使用浏览器缓存静态资源文件:更新静态资源文件时修改文件名
  3. 启用压缩:GZip 压缩
  4. CSS 放在页面最上面、JavaScript 放在页面最下面
  5. 减少 Cookie 传输:减少 Cookie 中传输的数据量;静态资源使用独立域名访问,减少 Cookie 传输的次数,突破浏览器连接限制

# CDN 加速

  • CDN(Content Distribute Network,内容分发网络),部署在网络运营商机房,通过将静态页面内容分发到离用户最近的 CDN 服务器,使用户可以通过最短路径获取内容

# 反向代理

  • 动静分离、负载均衡

# 应用服务器性能优化

# 分布式缓存

  • 网站访问数据的特点大多数呈现在"二八定律"(80% 的业务访问集中在 20% 的数据上),这时为了减轻数据的压力和提高网站的数据访问速度,则可以使用缓存机制来优化网站
  • 缓存的基本原理:数据缓存以一对 Key、Value 的形式存储在内存 Hash 表中,KV 对中 Key 的 HashCode 对应的 Hash 表索引
  • 分布式缓存架构:Memcached

# 异步操作

  • 将一个业务操作分成多个阶段,每个阶段之间通过共享数据的方式异步执行进行协作
  • 在单一服务器内部可通过多线程共享内存队列的方式实现异步,多个服务器集群通过分布式消息队列实现异步

# 使用集群

  • 多台服务器部署相同应用构成一个集群,通过负载均衡设备共同对外提供服务

# 代码优化

  1. 多线程
    解决线程安全:将对象设计为无状态对象、使用局部对象、并发访问资源时使用锁
  2. 资源复用:单例(Service、Dao)、对象池(数据库连接池、Web 应用服务器线程池)
  3. 数据结构
  4. 垃圾回收

# 存储性能优化

  • 机械硬盘 vs 固态硬盘、B+ 树 vs LSM 树、RAID vs HDFS

# 网站的高可用架构

  • 数据和服务的冗余备份及失效转移

# 高可用的应用

  • 位于应用层的服务器通过负载均衡设备将一组服务器组成一个集群共同对外提供服务

  • 当负载均衡设备通过心跳检测等手段监控到某台应用服务器不可用时,就将其从集群列表中剔除,并将请求分发到集群中其他可用的服务器上,使整个集群保持可用,从而实现应用高可用

  • 通过负载均衡进行无状态服务的失效转移

  • 应用服务器集群的 Session 管理

    • 在集群中的服务器之间同步 Session 对象(Session 复制)
    • 利用负载均衡的 ip_hash 算法实现 Session 绑定
    • 利用 Cookie 记录 Session
    • 利用独立部署的 Session 服务器(集群)统一管理 Session:利用分布式缓存、数据库等;利用 Session 服务集成单点登录(SSO)、用户服务等

# 高可用的服务

  • 位于服务层的服务器也是通过集群方式实现高可用

  • 这些服务器被应用层通过分布式服务调用框架访问,分布式服务调用框架会在应用层客户端程序中实现软件负载均衡,并通过服务注册中心对提供服务的服务器进行心跳检测,发现有服务不可用,立即通知客户端程序修改服务访问列表,剔除不可用的服务器

  • 高可用的服务策略

    1. 分级管理
    2. 超时设置
    3. 异步调用:对服务的调用通过消息队列等异步方式完成
    4. 服务降级:拒绝低优先级应用的调用、关闭不重要的服务
    5. 幂等性设计:保证服务重复调用和调用一次产生的结果相同

# 高可用的数据

# 数据备份

  • 位于数据层的服务器需要在数据写入时进行数据同步复制,将数据写入多台服务器上,实现数据冗余备份
  • 副本的数据一致性:强一致性(Strong Consistency)、弱一致性(Week Consistency)、会话一致性(Session Consistency)、最终一致性(Eventual Consistency)
  • 副本数据的分布方式主要有:哈希方式、按数据范围分布、按数据量分布、一致性哈希方式(Consistent Hashing)等
    • 一致性哈希的基本思路:使用一个哈希函数计算数据的哈希值,而哈希函数的输出值会作为一个封闭的环,根据哈希值将节点随机分布到这个环上,每个节点负责处理从自己开始顺时针至下一个节点的全部哈希值域上的数据。
  • 数据分布方式:
    • 以机器为核心时,机器之间互为副本,副本机器之间的数据完全相同
    • 以数据为核心时,一般将数据拆分为若干个数据段,以数据段为单位去分发
  • 副本分发策略
    • 中心化方式,由一个中心节点协调副本数据的更新、维护副本之间的一致性
    • 去中心化方式,没有中心节点,所有的节点都是 P2P 形式,地位对等,节点之间通过平等协商达到一致(缺点:各个节点达成共识的过程较长,需要反复进行消息通信来确认内容,实现较为复杂)

# 失效转移

  • 当数据服务器宕机时,应用程序将访问切换到有备份数据的服务器上

# 网站的伸缩性架构

  • 伸缩性:系统能够通过增加(减少)自身资源规模的方式增强(减少)自己计算处理事务的能力

# 网站架构的伸缩性设计

  • 根据不同功能进行物理分离实现伸缩:不同的服务器部署不同的服务,提供不同的功能(分层后分离、业务分割后分离)
  • 单一功能通过集群实现伸缩:集群内的多台服务器部署相同的服务,提供相同的功能

# 应用服务器集群的伸缩性设计

  • 利用 HTTP 重定向协议实现负载均衡
  • 利用 DNS 处理域名解析请求的同时进行负载均衡处理
  • 利用反向代理服务器进行负载均衡
  • 在网络层通过修改请求目标地址进行负载均衡
  • 在数据链路层修改 mac 地址进行负载均衡
  • 负载均衡算法:轮询(Round Robin,RR)、加权轮询(Weighted Round Robin, WRR)、随机(Random)、最少连接(Least Connections)、源地址散列(Source Hashing)

# 分布式缓存集群的伸缩性设计

  • Memcached、Redis
  • 一致性 Hash 算法

# 数据存储服务器集群的伸缩性设计

  • 关系数据库集群的伸缩性设计:数据库主从读写分离、数据分库、数据分片
  • NoSQL 数据库的伸缩性设计:HBase

# 网站的可扩展架构

  • 扩展性:对现有系统影响最小的情况下,系统功能可持续扩展或提升的能力
  • 模块化设计,并在此基础之上,降低模块间的耦合性,提高模块的复用性

# 利用分布式消息队列降低系统耦合性

  • 通过消息对象分解系统耦合性,不同子系统处理同一个消息
  • 事件驱动架构(Event Driven Architecture):通过在低耦合的模块之间传输事件消息,以保持模块的松散耦合,并借助事件消息的通信完成模块间合作
  • 将用户请求和其他业务事件构造成消息发布到消息队列,消息的处理者作为消费者从消息队列中获取消息进行处理
  • ActiveMQ、Kafka

# 利用分布式服务打造可复用的业务平台

  • 通过接口分解系统耦合性,不同子系统通过相同的接口描述进行服务调用

  • 纵向拆分:将一个大应用拆分为多个小应用

  • 横向拆分:将复用的业务拆分出来,独立部署为分布式服务

  • 常见分布式服务框架:Dubbo、Thrift、gRPC、Finagle

# 可扩展的数据结构

# 网站的安全架构

# 网站应用攻击与防范

# XSS 攻击

  • Cross Site Script,跨站点脚本攻击
  • 攻击者在网页中嵌入恶意脚本程序,在用户浏览网页时,控制用户浏览器进行恶意操作
  • 防范:对用户输入的数据中的“尖括号”、“单引号”、“引号”之类的特殊字符进行 HTML 转义处理

# CRSF 攻击

  • Cross Site Request Forgery,跨站点请求伪造
  • 攻击者利用了浏览器 cookie 或服务器 session 策略,盗取用户身份,然后通过跨站请求(存在 CSRF 漏洞的应用/网站),在用户不知情的情况下,以用户的身份伪造请求进行非法操作
  • 防范:在 cookie 中设置 "HttpOnly" 属性;增加 token 校验;通过 HTTP 头中的 Referer 识别该 HTTP 请求的来源地址

# SQL 注入攻击

  • 通过把 SQL 命令伪装成正常的 HTTP 请求参数,传递到服务端,欺骗服务器最终执行恶意的 SQL 命令,达到入侵目的
  • 防范:使用预编译语句;处理好相应的异常

# 文件上传漏洞

  • 攻击者利用一些站点没有对文件的类型做很好的校验,上传了可执行的文件或者脚本,并且通过脚本获得服务器上相应的权利,或者是通过诱导外部用户访问、下载上传的病毒或木马文件,达到攻击的目的
  • 防范:通过魔数来判断文件类型;对于图片类型的文件,在上传后对图片进行相应的缩放,破坏恶意用户上传的二进制可执行文件的结构,来避免恶意代码执行(ImageMagick)

# DDoS 攻击

  • Distributed Denial of Service,分布式拒绝服务攻击
  • 攻击者借助公共网络,将数量庞大的计算机设备联合起来作为攻击平台,对一个或多个目标发动攻击,消耗目标服务器性能或网络带宽,从而造成服务器无法正常地提供服务
  • 应对:高防 IP 是一种托管式的 DDoS 防护服务,将域名指向到高防 IP,通过将访问流量引流到 DDoS 防护服务器,对攻击流量进行彻底清洗过滤,并将正常流量返回源站,从而防护各种 DDoS/CC 攻击,确保源站稳定可用。

# 其它常见攻击手段

  • DNS 域名劫持、CDN 回源攻击、服务器权限提升、缓冲区溢出

# Web 应用防火墙

  • ModeSecurity

# 信息加密技术及密钥安全管理

# 信息加密技术

  • 单向散列加密:通过对不同输入长度的信息进行散列计算,得到固定长度的输出(数字摘要),常用算法:MD5、SHA、HMAC

    • HMAC(Hash-based Message Authentication Code),主要是利用哈希算法,以一个密钥和一个消息为输入,生成一个消息摘要作为输出,如 HMAC-MD5、HMAC-SHA256),用于验证传输于两个共同享有一个密钥的单位之间的消息
    • 加盐一般是把明文跟盐组合在一起,再进行 hash 计算;而 HMAC 则是将密钥 key 补位,然后与明文分组进行异或运算,并且将该输出与下一个分组进行异或运算,直到算出最后的 hash 值
    • 保存密码时推荐使用 org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder(BCrypt 是为保存密码设计的算法,相比 MD5 要慢很多)
  • 对称加密:加密和解密使用的密钥是同一个密钥(可以互相推算),常用算法:DES(Data Encrytion Standard)、RC5、AES(Advanced Encryption Standard)

    DES 由于秘钥太短,其为目前已知不安全加密算法

    AES 加密模式:

    • ECB:电子密码本模式,不安全,不推荐使用
    • CBC:密码分组链接模式,每次加密时初始化向量 IV 必须采用密码学安全的伪随机发生器(如 /dev/urandom),禁止填充全 0 等固定值
    • CFB:密文反馈模式
    • OFB:输出反馈模式
    • CTR:计数器模式
    • GCM:推荐使用,nonce 须采用密码学安全的伪随机数

    建议:把脱敏后的数据和密文保存在业务数据库,独立使用加密服务来做数据加解密;对称加密需要用到的密钥 secureKey 和初始化向量 iv,和业务数据库分开保存

  • 非对称加密:用公钥加密的信息必须用私钥才能解开,反之,用私钥加密的信息只有用公钥才能解开,常用算法:RSA

信息加密技术

# 数字签名

  • 签名主要包含两个过程:摘要非对称加密,首先对需要签名的数据做摘要(类似于常见的 MD5)后得到摘要结果,然后通过签名者的私钥对摘要结果进行非对称加密即可得到签名结果
  • 通信正文经过相应的摘要算法生成摘要后,使用消息发送者的私钥进行加密,生成数字签名,然后将消息正文与数字签名一起传输给信息的接收者
  • 接收者接收到消息的正文和对应的数字签名后,使用与发送端相同的摘要算法,生成通信正文的摘要,并且使用发送者的公钥对数字签名进行解密,得到发送端生成的摘要,进行比较后即可验证发送者的身份是否合法,正文的内容是否被篡改

# 数字证书

证书签名的生成

证书校验的过程

# 密钥安全管理

  • 把密钥和算法放在一个独立的服务器,对外提供加密和解密服务,应用系统通过调用这个服务,实现数据的加解密
  • 将加解密算法放在应用系统中,密钥则放在独立服务器中

# 信息过滤与反垃圾

分布式计算

Updated at: 2022-11-06 18:52:46